package com.ls.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ls.blog.dto.LikeDTO;
import com.ls.blog.dto.Recodes;
import com.ls.blog.dto.CommentDTO;
import com.ls.blog.dto.UserDetailsIml;
import com.ls.blog.entity.Comment;
import com.ls.blog.mapper.ArticleMapper;
import com.ls.blog.mapper.CommentMapper;
import com.ls.blog.service.CommentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ls.blog.utils.*;
import com.ls.blog.vo.CommentVO;
import com.ls.blog.vo.PageVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.ls.blog.common.consts.RedisKeyConst.COMMENT_LIKE;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lishun
 * @since 2022-01-14
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Resource
    private CommentMapper commentMapper;

    @Resource
    private ArticleMapper articleMapper;

    //存放迭代找出的所有子代的集合
    private List<Comment> tempReplys = new ArrayList<>();

    @Resource
    private HttpServletRequest request;

    @Resource
    RedisUtil redisUtil;

    /**
     * @Description: 查询评论
     * @Param: blogId：博客id
     * @Return: 评论消息
     */
    @Override
    public Recodes<CommentDTO> listCommentByArticleIdId(PageVO pageVO) {
        Recodes<CommentDTO> recodes = new Recodes<>();
        //查询文章父评论数量
        long count = this.count(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getArticleId, pageVO.getCid())
                .eq(Comment::getIsSure, 1)
                .isNull(Comment::getParentCommentId)
        );
        recodes.setTotal(count);
        List<CommentDTO> comments = commentMapper.listCommentByArticleIdId(PageUtils.translate(pageVO));
        if (Objects.isNull(comments) || comments.size()==0){
            return null;
        }
        // 以id分组
        List<Integer> parentsIds = comments.stream().map(CommentDTO::getId).collect(Collectors.toList());
        PageVO sonPageVo = new PageVO();
        sonPageVo.setCurrent(0L);
        sonPageVo.setIds(parentsIds);
        sonPageVo.setPageSize(3);
        List<CommentDTO> replyList = commentMapper.listReplys(sonPageVo);
        if (replyList!=null && replyList.size()>0){
            Map<Integer, List<CommentDTO>> replyMap = replyList.stream()
                    .peek(commentDTO -> {
                        // 设置点赞数量
                       commentDTO.setLikeCount((int) redisUtil.getBitCount(COMMENT_LIKE+commentDTO.getId()));
                    })
                    .collect(Collectors.groupingBy(CommentDTO::getParentCommentId));
            // 封装子评论
            List<CommentDTO> commentDTOList = comments
                    .stream()
                    .peek(commentDTO -> {
                // 设置点赞数量
                commentDTO.setLikeCount((int) redisUtil.getBitCount(COMMENT_LIKE+commentDTO.getId()));
                commentDTO.setReplyList(replyMap.get(commentDTO.getId()));
            }).collect(Collectors.toList());
            recodes.setRecodes(commentDTOList);
        }else {
            recodes.setRecodes(comments.stream().peek(commentDTO -> {
                // 设置点赞数量
                commentDTO.setLikeCount((int) redisUtil.getBitCount(COMMENT_LIKE+commentDTO.getId()));

            }).collect(Collectors.toList()));
        }

        return recodes;
    }

    //新增评论
    @Override
    public void saveComment(CommentVO commentVO) {
        // 获得当前登录信息
        UserDetailsIml currentUser = UserUtils.getCurrentUser();
        String ip = IpUtil.getIpAddr(request);
        Comment comment = ObjectUtils.copyObject(commentVO, Comment.class);
        comment.setCreateTime(LocalDateTime.now());
        comment.setUserId(currentUser.getId());
        comment.setIsSure(1);
        comment.setIp(ip);
        comment.setNickname(currentUser.getNickname());
        this.save(comment);
    }

    //删除评论
    @Override
    public void deleteComment(Integer id) {
//        Comment comment = commentMapper.selectById(id);
//        commentMapper.deleteComment(id);
//        TBlog tBlog = blogMapper.selectById(comment.getBlogId());
//        tBlog.setCommentCount(tBlog.getCommentCount() - 1);
//        blogMapper.updateById(tBlog);
//        blogMapper.getCommentCountById(comment.getBlogId());
    }

    //根据昵称查询评论
    @Override
    public List<Comment> findCommentByNickname(String nickname) {
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<Comment>();
        queryWrapper.like("nickname",nickname);
        //以创建时间排序（降序）
        queryWrapper.orderByDesc("create_time");
        List<Comment> tBlogList = commentMapper.selectList(queryWrapper);
        return tBlogList;
    }

    @Override
    public Recodes<CommentDTO> getCommentByPage(PageVO pageVO) {
        //1. 找出文章标题
        //2. 找出父评论信息

        List<CommentDTO> commentDTOS = commentMapper.listCommentDTO(pageVO);
        Recodes<CommentDTO> commentDTORecodes = new Recodes<>();
        commentDTORecodes.setRecodes(commentDTOS);
        return commentDTORecodes;
    }

    @Override
    public Recodes<CommentDTO> sureComments(PageVO pageVO) {
        long count = this.count(new LambdaQueryWrapper<Comment>().eq(Comment::getIsSure, 0));
        List<CommentDTO> commentDTOS = commentMapper.sureComments(PageUtils.translate(pageVO));
        Recodes<CommentDTO> commentDTORecodes = new Recodes<>();
        commentDTORecodes.setRecodes(commentDTOS);
        commentDTORecodes.setTotal(count);
        return commentDTORecodes;
    }

    @Override
    public void batchSureComments(List<Integer> ids) {
        this.update(new LambdaUpdateWrapper<Comment>().set(Comment::getIsSure,1).in(Comment::getId,ids));
    }

    @Override
    public void rejectSureComments(List<Integer> ids) {
        this.update(new LambdaUpdateWrapper<Comment>().set(Comment::getIsSure,-1).in(Comment::getId,ids));
    }

    @Override
    public Recodes<CommentDTO> replys(PageVO pageVO) {
        Recodes<CommentDTO> commentDTORecodes = new Recodes<>();
        long count = this.count(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getIsSure, 1)
                .eq(Comment::getParentCommentId, pageVO.getCid()));
        commentDTORecodes.setCurrent(pageVO.getCurrent());
        commentDTORecodes.setCurrentSize(pageVO.getPageSize());
        List<CommentDTO> replys = commentMapper.listReplys(PageUtils.translate(pageVO));
        commentDTORecodes.setTotal(count);
        commentDTORecodes.setRecodes(replys
                .stream()
                .peek(commentDTO -> {
            commentDTO.setLikeCount((int) redisUtil.getBitCount(COMMENT_LIKE+commentDTO.getId()));})
                .collect(Collectors.toList())
        );
        return commentDTORecodes;
    }

    @Override
    public LikeDTO  commentUp(Integer id) {
        LikeDTO likeDTO = new LikeDTO();
        // 评论点赞
        String key = COMMENT_LIKE + id;
        Long item = Long.valueOf(UserUtils.getCurrentUser().getId());
        boolean flag = redisUtil.getBit(key, item);
        redisUtil.setBit(key,item ,!flag);
        likeDTO.setFlag(false);
        long count = redisUtil.getBitCount(key);
        likeDTO.setCount((int) count);
        return likeDTO;
    }
}


